import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { ZodSchema } from 'zod';

@Injectable()
export class ZodValidationPipe implements PipeTransform {
  constructor(private schema: ZodSchema) { }

  transform(value: unknown, metadata: ArgumentMetadata) {
    try {
      // 验证传入的数据
      const result = this.schema.parse(value);
      return result;
    } catch (error) {
      console.log(error)
      // 处理验证错误
      const formattedErrors = this.formatZodError(error);

      throw new BadRequestException({
        message: '参数验证失败' + JSON.stringify(formattedErrors),
        errors: formattedErrors,
      });
    }
  }

  private formatZodError(error: any) {
    const formattedErrors = {};

    // 常见Zod错误类型的中文映射
    const errorMessages = {
      invalid_type: {
        string: '必须是字符串类型',
        number: '必须是数字类型',
        boolean: '必须是布尔类型',
        date: '必须是日期类型',
        array: '必须是数组类型',
        object: '必须是对象类型',
      },
      required_error: '此字段为必填项',
      too_small: {
        string: (min) => `长度不能小于${min}个字符`,
        number: (min) => `不能小于${min}`,
        array: (min) => `不能少于${min}项`,
      },
      too_big: {
        string: (max) => `长度不能超过${max}个字符`,
        number: (max) => `不能大于${max}`,
        array: (max) => `不能超过${max}项`,
      },
      invalid_string: {
        email: '邮箱格式不正确',
        url: 'URL格式不正确',
        uuid: 'UUID格式不正确',
        cuid: 'CUID格式不正确',
        regex: '格式不正确',
      },
      custom: '验证失败',
    };

    if (error.errors && Array.isArray(error.errors)) {
      error.errors.forEach((err) => {
        const path = err.path.join('.');

        // 根据错误类型生成中文提示
        let message = err.message;

        // 处理类型错误
        if (err.code === 'invalid_type') {
          if (err.received === 'undefined' || err.received === 'null') {
            message = errorMessages.required_error;
          } else if (errorMessages.invalid_type[err.expected]) {
            message = errorMessages.invalid_type[err.expected];
          }
        }

        // 处理长度/大小错误
        else if (err.code === 'too_small') {
          const type = err.type; // string, number, array等
          if (errorMessages.too_small[type]) {
            message = errorMessages.too_small[type](err.minimum);
          }
        }
        else if (err.code === 'too_big') {
          const type = err.type;
          if (errorMessages.too_big[type]) {
            message = errorMessages.too_big[type](err.maximum);
          }
        }

        // 处理字符串格式错误
        else if (err.code === 'invalid_string') {
          const validation = err.validation;
          if (errorMessages.invalid_string[validation]) {
            message = errorMessages.invalid_string[validation];
          }
        }

        formattedErrors[path] = message;
      });
    }

    return formattedErrors;
  }
} 